﻿#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
/*
表达式求值的顺序一部分是由操作符的优先级和结合性决定。
同样，有些表达式的操作数在求值的过程中可能需要转换为其他类型。
*/

/*
12.1 隐式类型转换

C的整型算术运算总是至少以缺省（默认）整型类型的精度来进行的。
为了获得这个精度，表达式中的字符和短整型操作数在使用之前被转换为普通整型，这种转换称为整型
提升。

整型提升的意义：

表达式的整型运算要在CPU的相应运算器件内执行，CPU内整型运算器(ALU)的操作数的字节长度
一般就是int的字节长度，同时也是CPU的通用寄存器的长度。
因此，即使两个char类型的相加，在CPU执行时实际上也要先转换为CPU内整型操作数的标准长
度。
通用CPU（general-purpose CPU）是难以直接实现两个8比特字节直接相加运算（虽然机器指令
中可能有这种字节相加指令）。所以，表达式中各种长度可能小于int长度的整型值，都必须先转
换为int或unsigned int，然后才能送入CPU去执行运算。
//实例1
char a,b,c;
...
a = b + c;
b和c的值被提升为普通整型，然后再执行加法运算。
加法运算完成之后，结果将被截断，然后再存储于a中。


如何进行整体提升呢？
整形提升是按照变量的数据类型的符号位来提升的

//int main()
//{
//	char c = -1;//-1是整数，32个比特位
//	//10000000000000000000000000000001
//	//11111111111111111111111111111110               原反补 反+1=补
//	//11111111111111111111111111111111 -> -1的补码
//	//11111111 - c（char 1个字节，8个比特位）
//	//11111111111111111111111111111111        //整型提升，看符号位，符号位是1，运算的时候，把前面全部补成1



//负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位：
1111111
因为 char 为有符号的 char
所以整形提升的时候，高位补充符号位，即为1
提升之后的结果是：
11111111111111111111111111111111

//正数的整形提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位：
00000001
因为 char 为有符号的 char
所以整形提升的时候，！高位（左边）补充符号位！符号位是第一个数
提升之后的结果是：
00000000000000000000000000000001




//无符号整形提升，高位补0


*/

//int 4byte - 32bit
//char 1byte- 8bit

//int main()
//{
//	//  原码是呈现的结果，补码是存储和运算的结果
//
//	char a = 5;
////	//00000000000000000000000000000101 - 5的二进制序列     //5存储的补码
////	//00000101 - a  符号位是第一个数 0         //a存储的补码
//	char b = 126;
////	//00000000000000000000000001111110  -- 126存储的补码
////	//01111110 - b  ，b存储的补码      //符号位是第一个数 0
//
//	char c = a + b;
////	//00000000000000000000000000000101 - a
////	//00000000000000000000000001111110 - b
////	//00000000000000000000000010000011   //a+b的补码             // 相加的时候，补位进行相加    (存储的是补码，补码运算）  int c的补码
////	//10000011 - c（char类型的c只能存放8个bite位） c存储的补码
////	//11111111111111111111111110000011 - 提升后的补码（提升属于运算，提升的是补码）
////	//11111111111111111111111110000010 - 反码
////	//10000000000000000000000001111101 - 原码
////  原码是呈现的结果，补码是存储和运算的结果
//	printf("%d\n", c);
//	//c = -125 ;
//	return 0;
//}


// int main()
//{
//	char a = 0xb6;
//	short b = 0xb600;
//	int c = 0xb6000000;
//
// 
// /*
// 但是 unsigned char a = 0xb6; 时，a为无符号类型，提升为0，提升后和原数没有差别，此时if语句判断为真，a也会打印
// 
// */
//	if (a == 0xb6)
//		printf("a");   //打印字符a
//
//	if (b == 0xb600)
//		printf("b");
//
// 
// //a，b都不是int类型，都进行类整型提升
// 实例1中的a,b要进行整形提升,但是c不需要整形提升
//a, b整形提升之后, 变成了负数, 所以表达式 a == 0xb6, b == 0xb600 的结果是假, 但是c不发生整形提升, 则表
//达式 c == 0xb6000000 的结果是真.
// 
// 
//	if (c == 0xb6000000)
//		printf("c");
//结果是只打印c
//	return 0;
//}



//int main()
//{
//	char c = 1;
//	printf("%u\n", sizeof(c));//1     （c是char，一个字节）
//	printf("%u\n", sizeof(+c));//4
//	printf("%u\n", sizeof(-c));//4
//此处 +c和-c（都是表达式）参与了整形运算，进行了整型提升，所以变成了整型类型，成了四个字节
//	return 0;
//}
//




/*
12.2 算术转换（大于等于整型）：向大的方向去转换
如果某个操作符的各个操作数属于不同的类型，那么除非其中一个操作数的转换为另一个操作数的类
型，否则操作就无法进行（向大转换）。下面的层次体系称为寻常算术转换。

long double
double
float
unsigned long int
long int
unsigned int
int
*/






/*
操作符的属性:

复杂表达式的求值有三个影响的因素。
1. 操作符的优先级
2. 操作符的结合性
3. 是否控制求值顺序。
两个相邻的操作符先执行哪个？取决于他们的优先级。如果两者的优先级相同，取决于他们的结合性。
操作符优先级


int fun()
{
     static int count = 1;
     return ++count;
}
在这个函数中，count被static修饰，成为静态变量，不会重建！会延用++count的数值
*/